package com.etoc.test.quartz;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Map;

import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.matchers.KeyMatcher;

import com.etoc.test.util.SpringContextHolder;


/**
 * 
 * 定时任务管理类
 *
 * @author 朱鹏
 * @author 陈超
 * @version  	[版本号, 2017年3月22日]
 * @see  		[相关类/方法]
 * @since  		[产品/模块版本]
 */
public class QuartzManager {
	
	private static final Logger logger = Logger.getLogger(QuartzManager.class);
	/**
	 * 上下文获取scheduler
	 */
    private static Scheduler scheduler = (Scheduler)SpringContextHolder.getBean("scheduler");
	
    /**
     * 增加一个定时任务
     * @param jobName			任务名称
     * @param jobGroupName		任务组名称
     * @param triggerName		触发器名称
     * @param triggerGroupName	触发器组名称
     * @param clazz				执行execute()的类
     * @param cronExpression	执行的时间规则（cron表达式）
     * @param paramsMap			需要传入到execute()里的参数
     */
    public static void addJob(String jobName,String jobGroupName,String triggerName,String triggerGroupName,
    		Class clazz, String cronExpression,Map<String,String> paramsMap) {  
        try {  
        	//任务
            JobDetail jobDetail = JobBuilder
            		.newJob(clazz)
            		.withIdentity(jobName, jobGroupName)
            		.withDescription(jobGroupName + "." + jobName + "任务")
            		.usingJobData(new JobDataMap(paramsMap))
            		.build();// 任务名，任务组，任务执行类
            // 触发器  
            /*CronTrigger cronTrigger = TriggerBuilder
            		.newTrigger()
            		.withIdentity(triggerName,triggerGroupName)
            		.withDescription(triggerGroupName + "." + triggerName + "触发器")
            	    .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
            	    .usingJobData("times", paramsMap.get("times"))
            	    .build();*/
         	Calendar calendar = new GregorianCalendar();
         	calendar.add(Calendar.SECOND, 30);
            SimpleTrigger cronTrigger = TriggerBuilder
            		.newTrigger()
            		.withIdentity(triggerName,triggerGroupName)
            		.withDescription(triggerGroupName + "." + triggerName + "触发器")
            	    .withSchedule(SimpleScheduleBuilder.simpleSchedule())
            	    .usingJobData("times", paramsMap.get("times"))
            	    .startAt(calendar.getTime())
            	    .build();
            scheduler.getListenerManager().addJobListener(new TestJobListener(), GroupMatcher.jobGroupEquals(TestJob.JOB_GROUP_NAME));
            scheduler.getListenerManager().addTriggerListener(new TestJobTriggerListener(), KeyMatcher.keyEquals(cronTrigger.getKey()));
            scheduler.getListenerManager().addSchedulerListener(new TestJobSchedulerListener());
            scheduler.scheduleJob(jobDetail, cronTrigger);  

            // 启动  
            if (!scheduler.isShutdown()) {  
            	scheduler.start();  
            }  
        } catch (Exception e) { 
        	logger.error("QuartzManager addJob is error !!!",e);
            throw new RuntimeException(e);  
        }  
    }  
    
    /** 
     * 修改一个任务的触发时间 
     * @param triggerName 			触发器名称
     * @param triggerGroupName		触发器组名称
     * @param cronExpression		执行的时间规则（cron表达式）
     */  
    public static void modifyTriggerTime(String triggerName, String triggerGroupName, String cronExpression) {  
        try {  
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName,triggerGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (trigger == null) {  
                return;  
            }  
            String oldTime = trigger.getCronExpression();  
            if (!oldTime.equalsIgnoreCase(cronExpression)) {  
            	// 触发器  
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // 触发器名,触发器组  
                triggerBuilder.withIdentity(triggerName, triggerGroupName);
                // 触发器时间设定  
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression));
                // 创建Trigger对象
                trigger = (CronTrigger) triggerBuilder.build();
                // 方式一 ：修改一个任务的触发时间
                scheduler.rescheduleJob(triggerKey, trigger);
            }  
        } catch (Exception e) {  
        	logger.error("QuartzManager modifyTriggerTime is error !!!",e);
            throw new RuntimeException(e);  
        }  
    }  
  
  
    /**
     * 删除任务及触发器
     * @param jobName				任务名称
     * @param jobGroupName			任务组名称
     * @param triggerName			触发器名称
     * @param triggerGroupName		触发器组名称
     * @see [类、类#方法、类#成员]
     */
    public static void removeJobAndTrigger(String jobName,String jobGroupName,String triggerName,String triggerGroupName) {  
        try {  
        	scheduler.pauseTrigger(TriggerKey.triggerKey(triggerName, triggerGroupName));// 停止触发器  
        	scheduler.unscheduleJob(TriggerKey.triggerKey(triggerName, triggerGroupName));// 移除触发器  
        	scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务  
        } catch (Exception e) {  
        	logger.error("QuartzManager removeJobAndTrigger is error !!!",e);
            throw new RuntimeException(e);  
        }  
    }
    
    /**
     * 停止触发器
     * @param triggerName			触发器名称
     * @param triggerGroupName		触发器组名称
     * @see [类、类#方法、类#成员]
     */
    public static void pauseTrigger(String triggerName,String triggerGroupName) {  
    	try
		{
			scheduler.pauseTrigger(TriggerKey.triggerKey(triggerName, triggerGroupName));// 停止触发器  
		} catch (Exception e) {
			logger.error("QuartzManager pauseTrigger is error !!!",e);
			throw new RuntimeException(e);
		}  
    }
    
    /**
     * 启动触发器
     * @param triggerName			触发器名称
     * @param triggerGroupName		触发器组名称
     * @param cronExpression		执行的时间规则（cron表达式）
     * @see [类、类#方法、类#成员]
     */
    public static void resumeTrigger(String triggerName,String triggerGroupName,String cronExpression) {  
    	try
		{
    		CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerName,triggerGroupName)
            	    .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
            	    .build();
			scheduler.rescheduleJob(TriggerKey.triggerKey(triggerName, triggerGroupName),cronTrigger);// 启动触发器
		} catch (Exception e) {
			logger.error("QuartzManager resumeTrigger is error !!!",e);
			throw new RuntimeException(e);
		}  
    }
    
    /** 
     * 启动所有定时任务 
     */  
    public static void startJobs() {  
        try {  
        	scheduler.start();  
        } catch (Exception e) {  
        	logger.error("QuartzManager startJobs is error !!!",e);
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * 关闭所有定时任务 
     */  
    public static void shutdownJobs() {  
        try {  
            if (!scheduler.isShutdown()) {  
            	scheduler.shutdown();  
            }  
        } catch (Exception e) {  
        	logger.error("QuartzManager shutdownJobs is error !!!",e);
            throw new RuntimeException(e);  
        }  
    }  
    
}
